/*!
// Testweb v0.4.0
// http://or-change.cn
// Copyright 2014 OrChange Inc. All rights reserved.
// Licensed under the GPL License.
*/

/**
 * EventStep extend from Step. This kind of Step will run after the
 * condition is true. In addition, it can be setted a timeout time.
 *
 * @module EventStep
 * @requires OC
 * @requires Step
 * @requires Condition
 * @example
 *     var EventStep = require("./oc.eventstep"); //How to require EventStep module.
 */
define(function (require, exports, module) {
	'use strict';
	var EventStep, OC = require("lib/core/oc"),
		Step = require("./step"),
		Condition = require("./condition");
	/**
	 * EventStep extend from Step. This kind of Step will run after the
	 * condition is true. In addition, it can be setted a timeout time.
	 *
	 * @class EventStep
	 * @extends Step
	 * @constructor
	 */

	EventStep = function EventStep(options) {
		/**
		 * Execute the step when the condition is true.
		 * @property condition
		 * @type condition
		 * @default null
		 */
		this.condition = options.condition || null;
		/**
		 * Cache the ID of interval timer (id of interval()).
		 * @property timer_id
		 * @type number
		 */
		this.timeout_id = 0;
		this.interval_id = 0;

		/**
		 * If the condition can't be true in timeout time,
		 * throw a timeout message.
		 *
		 * @property overtime
		 * @type number
		 * @default EVENT_TIMEOUT
		 */
		this.overtime = options.overtime || OC.cfg("EVENT_TIMEOUT");

		Step.call(this, options);
	};
	EventStep.prototype = new Step();
	EventStep.prototype.constructor = EventStep;
	/**
	 * EventStep default runing function.
	 * @method run
	 * @returns status {number}
	 */
	EventStep.prototype.run = function (callback) { // Condition checking overtime timer.
		var that = this;

		this.timeout_id = setTimeout(
			function () {
				clearInterval(that.interval_id);
				//TODO auto-restart process.
				console.log("time out!");
			},
			OC.cfg("EVENT_TIMEOUT")
		);
		// According to the designated interval to check the occurrence of the event.
		this.interval_id = setInterval(
			function () {
				if (that.condition.test() && that.$run()) {
					// When the event occurs, cancel the Interval
					// timer and Timeout timer.
					clearInterval(that.interval_id);
					clearTimeout(timeout_id);

					that.$process.$core();
				}
			},
			OC.cfg("EVENT_TEST_CYCLE")
		);
	};
	/**
	 * The timing and write results to Process.
	 * @method $timing
	 */
	EventStep.prototype.$timing = function () {
		var _process = this._process,
			p_length = _process.getLength(),
			counter = _process.getCounter(),
			loop = _process.loop,
			// The prev of the first step is the last of the program.
			prev = _process.program[(counter - 1 + p_length) % p_length];

		this._process.result[loop].delay =
			(this.run_timestamp - prev.run_timestamp);
	};
	EventStep.prototype.getViewData = function () {

	};
	EventStep.prototype.abort = function () {
		var interval_id = this.interval_id, timeout_id = this.timeout_id;
		clearInterval(interval_id);
		clearTimeout(timeout_id);
	};
	return EventStep;
});